/**
 * @file data_file.h
 *
 * @date Oct 5, 2011
 * @author seth
 *
 * @brief This file is part of EBEX State Estimator, created for the EBEX project
 *
 * This software is copyright (C) 2011 Columbia University
 *
 * EBEX State Estimator is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * EBEX State Estimator is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with EBEX State Estimator; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

#ifndef DATA_FILE_H_
#define DATA_FILE_H_

#include <stdio.h>
#include <stddef.h>
#include <stdbool.h>

#include <getdata.h>
#include <netcdf.h>

typedef enum
{
	DATA_FILE_NONE = 0,
	DATA_FILE_RAW,
	DATA_FILE_ASCII,
	DATA_FILE_DIRFILE,
	DATA_FILE_NETCDF
} data_file_types_t;

typedef enum
{
	DATA_UNIT_RADIANS = 0,
	DATA_UNIT_DEGREES = 1,

	DATA_UNIT_SECONDS = 0,
	DATA_UNIT_MS = 1,
} data_unit_types_t;

typedef struct
{
	size_t					column;
	char					*delimiters;
} data_file_ascii_conf_t;

typedef struct
{
	int					 	placeholder;
} data_file_raw_conf_t;

typedef struct
{
	size_t					spf;

	off_t					current_frame;
	off_t					current_sample;
	char					*field_code;
} data_file_dirfile_conf_t;

typedef struct
{
	int						field_code;
} data_file_netcdf_conf_t;

typedef struct
{
	data_file_types_t		type;
	bool					is_sink;
	data_unit_types_t		units;

	char					*filename;
	size_t					num_elements;
	size_t					offset;
	size_t					stride;

	union
	{
		FILE				*fp;
		DIRFILE				*dirfile_fp;
		int					netcdf_fd;
	};

	union
	{
		data_file_raw_conf_t		raw;
		data_file_ascii_conf_t		ascii;
		data_file_dirfile_conf_t	dirfile;
		data_file_netcdf_conf_t		netcdf;
	} conf;

} data_file_t;

typedef struct
{
	data_file_t				*timefile;
	data_file_t				*datafile;
	size_t					num_datafiles;

	size_t					buffer_size;
	size_t					buffer_produced;
	size_t					buffer_consumed;

	double					*timebuffer;
	double					**databuffer;
} data_source_t;

typedef struct
{
	void					(*file_close)(data_file_t*);
	bool 					(*file_open)(data_file_t*, const char*, size_t);
	bool					(*file_reset)(data_file_t*);
	size_t 					(*fill_buffer)(data_file_t *, double *, const size_t);
	size_t 					(*write_buffer)(data_file_t *, double *, const size_t);
	bool					(*set_parameters)(data_file_t *, const void *);
} data_source_interface_t;


bool ebex_data_close_source(data_source_t *m_this);
data_source_t *ebex_data_new_source(const size_t m_buffersize);
bool ebex_data_resize(data_source_t *m_source, const size_t m_buffersize);
size_t ebex_data_reorganize(data_source_t *m_source);
bool ebex_data_reset_source(data_source_t *m_source);
data_file_t *ebex_data_add_datafile(data_source_t *m_source, const char *m_filename, data_file_types_t m_type, size_t m_offset, bool m_forwriting);
data_file_t *ebex_data_set_timefile(data_source_t *m_source, const char *m_filename, data_file_types_t m_type, size_t m_offset, bool m_forwriting);
size_t ebex_data_fill_buffer(data_source_t *m_source, size_t m_num);
size_t ebex_data_write_buffer(data_source_t *m_source);
bool ebex_data_set_parameters(data_file_t *m_file, const void *m_parameters);

size_t ebex_data_copy_to_buffer(data_source_t *m_source, size_t m_buffer, const double *m_data, size_t m_num);
size_t ebex_data_copy_time_to_buffer(data_source_t *m_source, const double *m_data, size_t m_num);

size_t ebex_data_copy_to_buffer_by_dirfile_field(data_source_t *m_source, const char *m_buffer, const double *m_data, size_t m_num);

#endif /* DATA_FILE_H_ */
